package web.beans;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.faces.context.FacesContext;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import ejb.entities.*;
import ejb.facade.UserFacade;
import ejb.facade.EventFacade;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;

@RequestScoped
@Named
public class UserBean {
    
    @Inject
    private Login login;
    
	private User currentUser;
	private User user;

	private String oldpwd;
	private String newpwd;
	private int count;
	private int roleId;

	@EJB
	private UserFacade uFacade;

	@EJB
	private EventFacade sFacade;

        //GETTER Functions
    public Login getLogin() {
        return login;
    }

    public int getCount() {
        return count;
    }

    public UserFacade getuFacade() {
        return uFacade;
    }

    public EventFacade getsFacade() {
        return sFacade;
    }

    public User getUser() {
	return user;
    }

    //SETTER Functions
        
     public void setLogin(Login login) {
        this.login = login;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public void setuFacade(UserFacade uFacade) {
        this.uFacade = uFacade;
    }
    public void setsFacade(EventFacade sFacade) {
        this.sFacade = sFacade;
    }

    public void setUser(User user) {
        this.user = user;
    }

    //public UserBean() {
    //		user = new User();
    //	}

	@PostConstruct
	public void Init() {
		oldpwd = null;
                newpwd = null;
                if(login.getUser()==null){
                    user = new User();
                }else{
                    setUser(login.getUser());
                }
	}

	public void register() throws AddressException, MessagingException {                 
		String pwd = user.getPassword();
                user.setGroupname("USER");
                //Search if there is a user with the same Username registered yet
                if(uFacade.findUserByUsername(user.getUsername()) != null){
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Username already in use!"));
                }else{
                if(isValidPasw(pwd)){    
                    if (uFacade.saveNewUser(user)) {
                        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Saved!", "Registration was successfull!"));		
			// authenticates the newly registered user
			HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
                            try {
				request.login(user.getUsername(), pwd);
                                this.login.setUser(user);
                                this.login.goToHome();
                            } catch (ServletException e) {
                            	FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Security Error! Please provide correct data!"));		
                            }						
                    } else {
                           FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Login Error! Please provide correct data!"));		
                    }
                    }else{
                          	FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Password not valid! Only numbers are not allowed!]"));		                          
                    }
                }
	}
        
        public boolean isValidPasw(String pwd){
            char c;  
            int count = 0;   
            for (int i = 0; i < pwd.length(); i++) {  
                c = pwd.charAt(i);  
                if (!Character.isLetterOrDigit(c)) {          
                    return false;  
                } else if (Character.isDigit(c)) {  
                    count++;     
                }   
            }
            if (count == pwd.length())   {     
                return false;  
            }  
            return true;
        }

	public void updateUser() {

		if (uFacade.updateUser(user)) {
                        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Saved!", "Profile updated successfully!"));
		} else {
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Please provide correct data!"));
		}

	}

	public void updatePassword() {
		if (uFacade.updatePassword(user, oldpwd, newpwd)) {
                     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Saved!", "Password updated successfully!"));
		} else {
                     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Please provide correct data!"));
		}

	}

	public int getRoleId() {
		return roleId;
	}

	public void setRoleId(int roleId) {
		this.roleId = roleId;
	}

	public User getCurrentUser() {
		return currentUser;
	}

	public void setCurrentUser(User currentUser) {
		this.currentUser = currentUser;
	}


	public String getNewpwd() {
		return newpwd;
	}

	public void setNewpwd(String newpwd) {            
		String hashedPassword = encryptPsw(newpwd);
		this.newpwd = hashedPassword;
	}

	public String getOldpwd() {
		return oldpwd;
	}

	public void setOldpwd(String oldpwd) {
		String hashedPassword = encryptPsw(oldpwd);
		this.oldpwd = hashedPassword;
	}

	/*public List<Nomcity> getCitiesForCountry() {
		List<Nomcity> l = new ArrayList<Nomcity>(0);
		if (user != null && user.getCountry() != null) {
			for (Nomcity c : common_data.getCities()) {
				if (c.getCountry().getId() == user.getCountry().getId())
					l.add(c);
			}

		}
		citiesForCountry = l;
		return l;
	}

	public void setCitiesForCountry(List<Nomcity> citiesForCountry) {
		this.citiesForCountry = citiesForCountry;
	}*/
        
        public String encryptPsw(String clearPsw)
        {
            try {
                MessageDigest digest = MessageDigest.getInstance("SHA-256");
                byte[] hash = digest.digest(clearPsw.getBytes("UTF-8"));
                BigInteger bigInt = new BigInteger(1, hash);
                clearPsw = bigInt.toString(16);
            } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
                Logger.getLogger(User.class.getName()).log(Level.SEVERE, null, ex);
            }
            return clearPsw;
        }
        
}
